package com.ds.infrastructure.hyperspace.console.controller;

import com.ds.infrastructure.hyperspace.console.common.methodlock.MethodLockId;
import com.ds.infrastructure.hyperspace.console.dto.deploydata.HostGroupDTO;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbDeployConfigEnum;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbPublicEnum;
import com.ds.infrastructure.hyperspace.console.entity.table.TbDeployConfig;
import com.ds.infrastructure.hyperspace.console.entity.table.TbDeployInstallTask;
import com.ds.infrastructure.hyperspace.console.entity.table.TbDeployNode;
import com.ds.infrastructure.hyperspace.console.entity.table.TbStage;
import com.ds.infrastructure.hyperspace.console.exceptions.HyperspaceException;
import com.ds.infrastructure.hyperspace.console.model.request.deploy.ActiveForm;
import com.ds.infrastructure.hyperspace.console.model.request.deploy.DeployForm;
import com.ds.infrastructure.hyperspace.console.model.request.deploy.GetHostGroupForm;
import com.ds.infrastructure.hyperspace.console.model.request.deploy.SaveDeployForm;
import com.ds.infrastructure.hyperspace.console.model.response.deploy.GetHostGroupVO;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResult;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultData;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultOk;
import com.ds.infrastructure.hyperspace.console.service.inf.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @author: yaozhendong
 * @create: 2019-10-21 10:36
 **/
@RestController
@RequestMapping(value = "/deploy", produces = {"application/json;charset=UTF-8"})
@Api(value = "Manager Deploy Controller", tags = "部署管理")
public class DeployController {
    @Autowired
    IDeployConfigService iDeployConfigService;
    @Autowired
    IStageService iStageService;
    @Autowired
    IDeployManageService iDeployManageService;
    @Autowired
    IDeployInstallTaskService iDeployInstallTaskService;
    @Autowired
    IDeployNodeService iDeployNodeService;

    @GetMapping(value = "/get")
    @ApiOperation(value = "查看-部署配置数据")
    public JsonResultData<SaveDeployForm> get(@RequestParam(name = "stageId") Long stageId) {
        TbStage tbStageEntity = iStageService.getOrThrow(stageId);
        TbDeployConfig entity = iDeployConfigService.selectLastOne(tbStageEntity.getId(), tbStageEntity.getEnvironmentId());
        if (entity == null) {
            entity = iDeployConfigService.getLastOneWithMethodLockId(MethodLockId.newId(stageId), tbStageEntity.getId(), tbStageEntity.getEnvironmentId());
        }
        SaveDeployForm result = SaveDeployForm.toVO(entity);
        return JsonResultData.build(result);
    }

    @PostMapping(value = "/save")
    @ApiOperation(value = "保存-部署配置数据")
    public JsonResult save(@RequestBody @Valid SaveDeployForm form) {

        TbDeployConfig oldEntity = iDeployConfigService.get(form.getId());
        if (oldEntity == null) {
            throw new HyperspaceException("保存部署配置数据失败，没有找到对应的记录，id=" + form.getId());
        }
        if (TbDeployConfigEnum.EDIT_STATE.NO.code.equals(oldEntity.getEditState())) {
            throw new HyperspaceException("当前部署记录已被激活，不可编辑");
        }

        TbDeployConfig newEntity = SaveDeployForm.toEntity(form);
        int count = iDeployConfigService.updateWithTimestamp(newEntity);
        if (count == 0) {
            throw new HyperspaceException("当前部署记录修改失败，数据时间戳不一致。当前记录已被修改");
        }
        return JsonResultOk.SUCCESS;
    }

    @PostMapping(value = "/getHostGroup")
    @ApiOperation(value = "获取-HostGroup")
    public JsonResultData<GetHostGroupVO> getHostGroup(@RequestBody @Valid GetHostGroupForm form) {
        TbStage tbStageEntity = iStageService.getOrThrow(form.getStageId());
        TbDeployInstallTask tbDeployInstallTask = iDeployInstallTaskService.selectLastOneForExecuteSuccess(tbStageEntity.getId(), tbStageEntity.getEnvironmentId());
        if (tbDeployInstallTask == null) {
            throw new HyperspaceException("部署安装任务没有找到， stageId=" + form.getStageId());
        }
        if (!TbPublicEnum.TASK_COMPLETE_STATE.COMPLETE.value.equals(tbDeployInstallTask.getCompleteState())) {
            throw new HyperspaceException("最新的部署任务没有完成！deployTaskId=" + tbDeployInstallTask.getId());
        }
        List<TbDeployNode> tbDeployNodeList = iDeployManageService.getDeployNode(tbDeployInstallTask.getId(), form.getHostGroupIsActive());
        GetHostGroupVO result = GetHostGroupVO.toVO(tbDeployInstallTask.getId(), tbDeployNodeList);
        return JsonResultData.build(result);
    }


    @PostMapping(value = "/install")
    @ApiOperation(value = "安装-网关应用程序")
    public JsonResultData<Long> install(@RequestBody @Valid DeployForm form) {
        TbDeployConfig entity = iDeployConfigService.get(form.getId());
        SaveDeployForm.checkConfigData(entity);
        if (entity == null) {
            throw new HyperspaceException("激活部署配置失败，没有找到对应的记录，id=" + form.getId());
        }
        if (TbDeployConfigEnum.EDIT_STATE.NO.code.equals(entity.getEditState())) {
            throw new HyperspaceException("安装-网关应用程序失败，当前配置为不可编辑，tbDeployConfigId=" + entity.getId());
        }
        List<HostGroupDTO> hostGroupDTOList = iDeployManageService.getHostGroupDTOList(entity, form.getHostGroupIds());
        Long taskId = iDeployManageService.deploy(MethodLockId.newId(entity.getStageId()), entity, hostGroupDTOList);
        iDeployManageService.executeDeployTask(taskId);
        return JsonResultData.build(taskId);
    }

    @PostMapping(value = "/active")
    @ApiOperation(value = "激活-启动网关应用程序")
    public JsonResultData<Long> active(@RequestBody @Valid ActiveForm form) {
        Long taskId = iDeployManageService.active(form.getDeployTaskId(), form.getHostGroupIds());
        iDeployManageService.executeActiveTask(taskId);
        return JsonResultData.build(taskId);
    }
}
